package com.baizhi.config;

import com.baizhi.realm.AuthenRealm;
import com.baizhi.realm.AuthorRealm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * shiro 配置类
 */
@Configuration
public class ShiroConfig {
    /**
     * 日志打印
     */
    Logger logger = LoggerFactory.getLogger(ShiroConfig.class);

    /**
     * 创建过滤器工厂  过滤器只需要配置 不需要自己创建  框架做好了
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        logger.debug("创建拦截器");
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        /**
         * 设置过滤器的拦截规则
         * anon 匿名可访问  不需要认证就可以访问
         * authc  认证可访问  需要认证通过才能访问
         *
         */
        Map map = new HashMap();
        map.put("/login.jsp","anon");
        map.put("/admin/*","anon");
        map.put("/jsp/*","authc");
        map.put("/main.jsp","authc");
        map.put("/guru/*","authc");

        factoryBean.setFilterChainDefinitionMap(map);

//        设置安全管理器
        factoryBean.setSecurityManager(securityManager);
        return factoryBean;
    }


    /**
     * 创建安全管理器
     * @return
     *
     *  @Bean 加在方法上  方法的形参 如果对应的类型的对象在工厂有  会自动装配上
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(AuthorRealm authorRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//        设置自定义Realm
        securityManager.setRealm(authorRealm);
        return securityManager;
    }

    /**
     * 创建自定义的Realm
     */
    @Bean
    public AuthorRealm authorRealm(){
        return new AuthorRealm();
    }


    /**
     *  开启shiro aop注解支持
     *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
